package com.example.administrator.zxygradute;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.RelativeLayout;

public class PDAMainPageSwipeLayout extends RelativeLayout {

    private Context mContext;
    private ViewGroup leftView, mainView;
    private boolean needInterupt = false;
    private ValueAnimator animator;
    private ValueAnimator.AnimatorUpdateListener listener;
    private boolean isCloseAnim;
    private long defaultHalfScreenScrollTime = 300;
    private float curMovePercent;

    public PDAMainPageSwipeLayout(Context context) {
        super(context);
        initView(context);
    }

    public PDAMainPageSwipeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public PDAMainPageSwipeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private void initView(Context context) {
        mContext = context;
        mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
        animator = ObjectAnimator.ofFloat(0f, 1f).setDuration(300);
        animator.addUpdateListener(listener = new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float percent = (float) animation.getAnimatedValue();

                if (isCloseAnim) {
                    mainView.scrollTo((int) (-deltaXMain * (1 - percent)), 0);
                    leftView.scrollTo((int) -((1 - percent) * deltaXLeft), 0);
                } else {
                    mainView.scrollTo((int) (-deltaXMain + (deltaXMain - leftWidth) * percent), 0);
                    leftView.scrollTo((int) -(percent * (leftOffset - deltaXLeft) + deltaXLeft), 0);
                }

                curMovePercent = -mainView.getScrollX() * 1f / leftWidth;
                if (status == STATUS_OPEN) {
                    curMovePercent = 1 - curMovePercent;
                }

                if (onScrollListener != null) {
                    boolean flag = status == STATUS_CLOSE;
                    onScrollListener.onScroll(curMovePercent, status, flag ? STATUS_OPEN : STATUS_CLOSE);
                }

                if (percent == 1) {
                    if (status == STATUS_CLOSE) {
                        if (!isCloseAnim) {
                            status = STATUS_OPEN;
                        }
                    } else {
                        if (isCloseAnim) {
                            status = STATUS_CLOSE;
                        }
                    }
                }

            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        try {
            if (getChildCount() > 1) {
                leftView = (ViewGroup) getChildAt(0);
                mainView = (ViewGroup) getChildAt(1);
                leftWidth = leftView.getWidth();
                leftOffset = -leftView.getPaddingLeft();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private float downX, downY, deltaXMain, deltaYMain, deltaXLeft, startMainX;
    private float mTouchSlop;
    private float leftWidth, leftOffset;
    private int status = STATUS_CLOSE;
    public final static int STATUS_CLOSE = 0x01; //收回状态
    public final static int STATUS_OPEN = 0x02; //弹出状态
    private VelocityTracker tracker;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        if (leftView == null || mainView == null || leftWidth == 0 || !isEnabled()) {
//            allowParentsInterceptTouchEvent(getParent());
            needInterupt = false;
            return super.dispatchTouchEvent(ev);
        }

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                disallowParentsInterceptTouchEvent(getParent());
                animator.cancel();
                downX = ev.getRawX();
                downY = ev.getRawY();
                startMainX = -mainView.getScrollX();
                needInterupt = false;
                break;
            case MotionEvent.ACTION_MOVE:
                deltaXMain = ev.getRawX() - downX;
                deltaYMain = ev.getRawY() - downY;
//                if(Math.abs(ev.getRawY() - downY) > mTouchSlop){
//                    allowParentsInterceptTouchEvent(getParent());
//                    return false;
//                }else
                if(!needInterupt && Math.abs(deltaYMain) > mTouchSlop){
                    break;
                }else if (!needInterupt && Math.abs(deltaXMain) > mTouchSlop) {
                    needInterupt = true;
                }

//                if(needInterupt){
//                    if(deltaXMain > 0){
//                        if(deltaXMain - mTouchSlop > 0){
//                            deltaXMain -= mTouchSlop;
//                        }
//                    }else{
//                        deltaXMain += mTouchSlop;
//                        if(deltaXMain > leftWidth){
//                            deltaXMain = leftWidth;
//                        }
//                    }
//                }


                break;
        }

        return super.dispatchTouchEvent(ev);
//        return needInterupt;
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (needInterupt) {
            return true;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {


        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:

                if (needInterupt) {
                    if (tracker == null)
                        tracker = VelocityTracker.obtain();
                    tracker.addMovement(event);

                    deltaXMain += startMainX;
                    curMovePercent = deltaXMain / leftWidth;
                    if (curMovePercent > 1) {
                        deltaXMain = leftWidth;
                        curMovePercent = 1;
                    } else if (curMovePercent < 0) {
                        deltaXMain = 0;
                        curMovePercent = 0;
                    }
                    deltaXLeft = curMovePercent * leftOffset;
                    mainView.scrollTo((int) -deltaXMain, 0);
                    leftView.scrollTo((int) -deltaXLeft, 0);
                    if (onScrollListener != null) {
                        boolean flag = status == STATUS_CLOSE;
                        onScrollListener.onScroll(flag ? curMovePercent : 1 - curMovePercent, status, flag ? STATUS_OPEN : STATUS_CLOSE);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:

                if (needInterupt) {

                    float speedX = 0;

                    if(tracker != null){
                        tracker.computeCurrentVelocity(500);
                        speedX = tracker.getXVelocity();
                    }

                    long duration;

                    if (Math.abs(speedX) > 500) {
                        if (speedX >= 0) {//右划
                            isCloseAnim = false;
                            duration = (long) ((leftWidth - deltaXMain) / speedX * 1000);
                        } else {//左划
                            isCloseAnim = true;
                            duration = (long) (deltaXMain / -speedX * 1000);
                        }
                    } else {
                        isCloseAnim = deltaXMain > mainView.getWidth() / 2 ? false : true;
                        if (isCloseAnim) {
                            duration = (long) (deltaXMain / (mainView.getWidth() / 2) * defaultHalfScreenScrollTime);
                        } else {
                            duration = (long) ((leftWidth - deltaXMain) / (mainView.getWidth() / 2) * defaultHalfScreenScrollTime);
                        }
                    }

                    duration = duration > defaultHalfScreenScrollTime ? defaultHalfScreenScrollTime : duration;
                    duration = duration < 100 ? 100 : duration;

                    animator.setDuration(duration);

                    if (deltaXMain != 0 && deltaXMain != leftWidth) {
                        animator.start();
                    }

                }

                break;
        }
        return true;
    }

    public int getStatus() {
        return status;
    }

    public void close() {
        if (mainView.getScrollX() < 0) {
            isCloseAnim = true;
            deltaXMain = leftWidth;
            deltaXLeft = leftOffset;
            animator.start();
        }
    }

    public void open() {
        if (mainView.getScrollX() > -leftWidth) {
            isCloseAnim = false;
            deltaXMain = 0;
            deltaXLeft = 0;
            animator.start();
        }
    }

    private void disallowParentsInterceptTouchEvent(ViewParent parent) {
        if (null == parent) {
            return;
        }
        parent.requestDisallowInterceptTouchEvent(true);
        disallowParentsInterceptTouchEvent(parent.getParent());
    }

    private void allowParentsInterceptTouchEvent(ViewParent parent) {
        if (null == parent) {
            return;
        }
        parent.requestDisallowInterceptTouchEvent(false);
        allowParentsInterceptTouchEvent(parent.getParent());
    }

    public interface OnScrollListener {
        /**
         * @param percent    滑动百分比
         * @param fromStatus 从哪个状态
         * @param toStatus   到哪个状态
         */
        public void onScroll(float percent, int fromStatus, int toStatus);
    }

    public OnScrollListener onScrollListener;

    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }
}
